/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmlasm.bo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import utils.XMLUtils;
import xmlasm.dto.Feeds;
import xmlasm.dao.FeedDAO;
import xmlasm.dto.Feed;
import xmlasm.sync.FilePathHolder;

/**
 *
 * @author Hoang
 */
public class FeedBO {

    public static void loadFeedsAndMarshall() {
        Feeds feeds = FeedDAO.getAllFeeds();
        //Marshall xuống file xml
        XMLUtils.writeObjectToXML(FilePathHolder.getInstance().getFeedXMLPath(), feeds);
    }

    public static Feed getRssFromRSSLink(String rssLink) {
        Feeds feeds = (Feeds) XMLUtils.getObjectFromXML(
                FilePathHolder.getInstance().getFeedXMLPath(), Feeds.class);
        for (Feed feed : feeds.getFeed()) {
            if (feed.getUrl().equals(rssLink)) {
                return feed;
            }
        }
        return null;
    }

    //Dua id vao, lay link ra de bat dau parse
    public static String getRSSLinkFromID(int rssID) {
        InputStream is = null;
        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = null;
        try {
            is = new FileInputStream(FilePathHolder.getInstance().getFeedXMLPath());
            xsr = xif.createXMLStreamReader(is);
            while (xsr.hasNext()) {
                int cursor = xsr.next();
                if (cursor == XMLStreamConstants.START_ELEMENT) {
                    //Bat dau element feedID
                    if (xsr.getLocalName().equals("feedId")) {
                        xsr.next(); //Toi character
                        int rsID = Integer.parseInt(xsr.getText().trim());
                        //Neu tim duoc, nhay tag
                        if (rsID == rssID) {
                            xsr.next(); //End feedID element
                            xsr.nextTag(); //Begin url element
                            if (xsr.getLocalName().equals("url")) {
                                xsr.next(); //Character của url
                                String result = xsr.getText().trim();
                                return result;
                            } //End element url
                        } // End rssID find
                    } //End if begin feeđID
                } // End start element
            }
        } catch (XMLStreamException ex) {
            ex.printStackTrace();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            if (xsr != null) {
                try {
                    xsr.close();
                } catch (XMLStreamException ex) {
                    ex.printStackTrace();
                }
            }
        }
        return "";
    }

    public static void insertFeedToXML(Feed feed) {
        Feeds feeds = (Feeds) XMLUtils.getObjectFromXML(
                FilePathHolder.getInstance().getFeedXMLPath(), Feeds.class);
        feeds.getFeed().add(feed);
        XMLUtils.writeObjectToXML(
                FilePathHolder.getInstance().getFeedXMLPath(), feeds);
    }

    public static void setAssociationToXML(int userID, int feedID) {

        Feeds feeds = (Feeds) XMLUtils.getObjectFromXML(
                FilePathHolder.getInstance().getFeedXMLPath(), Feeds.class);
        for (Feed feed : feeds.getFeed()) {
            if (feed.getFeedId() == feedID) {
                feed.getUserlist().getUserId().add(userID);
                break;
            }
        }
        XMLUtils.writeObjectToXML(
                FilePathHolder.getInstance().getFeedXMLPath(), feeds);


    }

    public static void removeAssociationFromXML(int userID, int feedID) {

        Feeds feeds = (Feeds) XMLUtils.getObjectFromXML(
                FilePathHolder.getInstance().getFeedXMLPath(), Feeds.class);
        for (Feed feed : feeds.getFeed()) {
            if (feed.getFeedId() == feedID) {
                feed.getUserlist().getUserId().remove(new Integer(userID));
                break;
            }
        }
        XMLUtils.writeObjectToXML(
                FilePathHolder.getInstance().getFeedXMLPath(), feeds);

    }

    public static boolean updateFeedXML(int feedID, String title, String description) {
        try {
            Document dom = XMLUtils.parseDom(FilePathHolder.getInstance().getFeedXMLPath());
            boolean result = updateFeedXML(dom, feedID, title, description);
            if (result) {
                XMLUtils.writeDOMtoXML(FilePathHolder.getInstance().getFeedXMLPath(), dom);
            }
            return result;
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(FeedBO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(FeedBO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(FeedBO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    private static boolean updateFeedXML(Node node, int feedID, String title, String description) {
        if (node == null) {
            return false;
        }

        if (node.getNodeName().equals("feed")) {
            NodeList feedChildren = node.getChildNodes();
            for (int i = 0; i < feedChildren.getLength(); i++) {
                Node temp1 = feedChildren.item(i);
                if (temp1.getNodeName().equals("feedId")) {
                    int id = Integer.parseInt(temp1.getTextContent());
                    if (id == feedID) {
                        for (int j = i; j < feedChildren.getLength(); j++) {
                            Node temp2 = feedChildren.item(j);
                            if (temp2.getNodeName().equals("title")) {
                                temp2.setTextContent(title);
                            }
                            if (temp2.getNodeName().equals("decription")) {
                                temp2.setTextContent(description);
                            }
                            
                        }
                        return true;
                    }
                }
            }
        }
        NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            boolean result = updateFeedXML(childNodes.item(i), feedID, title, description);
            if (result) {
                return result;
            }
        }
        return false;
    }

    public static boolean deleteFeedFromXML(int feedID) {
        try {
            Document dom = XMLUtils.parseDom(FilePathHolder.getInstance().getFeedXMLPath());
            boolean result = deleteFeedFromXML(dom, feedID);
            if (result) {
                XMLUtils.writeDOMtoXML(FilePathHolder.getInstance().getFeedXMLPath(), dom);
            }
            return result;
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(FeedbackBO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(FeedbackBO.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(FeedbackBO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    private static boolean deleteFeedFromXML(Node node, int feedID) {
        if (node == null) {
            return false;
        }

        if (node.getNodeName().equals("feedId")) {
            if (feedID == Integer.parseInt(node.getTextContent())) {
                Node feed = node.getParentNode(); 
                Node feeds = feed.getParentNode();
                feeds.removeChild(feed);
                return true;
            }
        }

        NodeList childOfNodes = node.getChildNodes();
        for (int i = 0; i < childOfNodes.getLength(); i++) {
            boolean result = deleteFeedFromXML(childOfNodes.item(i), feedID);
            if (result) {
                return result;
            }
        }
        return false;
    }
}
